﻿using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint.WebPartPages;
using Microsoft.SharePoint;

namespace GoogleMapWebPart
{


    [Guid("d269a415-e85b-4260-8d96-ae0da51640f3"), CLSCompliant(true)]
    public class GoogleMapWebPart : Microsoft.SharePoint.WebPartPages.WebPart
    {
        public GoogleMapWebPart()
        {

        }
        string jsArray = string.Empty;
        string jsCenter = string.Empty;

        [WebBrowsable(true), Personalizable(true), Bindable(true), Browsable(false), Category("Settings"), DefaultValue(""), WebPartStorage(Storage.Shared), FriendlyName("List Name"), Description("List Name.")]
        public string ListName { get; set; }

        [WebBrowsable(true), Personalizable(true), Bindable(true), Browsable(true), Category("Settings"), DefaultValue(""), WebPartStorage(Storage.Shared), FriendlyName("Long Field"), Description("Long Field located in the List.")]
        public string LongField { get; set; }

        [WebBrowsable(true), Personalizable(true), Bindable(true), Browsable(false), Category("Settings"), DefaultValue(""), WebPartStorage(Storage.Shared), FriendlyName("Lat Field"), Description("Lat Field located in the List.")]
        public string LatField { get; set; }

        [WebBrowsable(true), Personalizable(true), Bindable(true), Browsable(false), Category("Settings"), DefaultValue(""), WebPartStorage(Storage.Shared), FriendlyName("API Key"), Description("Google API Key.")]
        public string APIKey { get; set; }

        [WebBrowsable(true), Personalizable(true), Bindable(true), Browsable(false), Category("Settings"), DefaultValue(""), WebPartStorage(Storage.Shared), FriendlyName("Enable Wheel Zoom"), Description("Mouse Wheel Zoom.")]
        public bool enableScrollWheelZoom { get; set; }

        [WebBrowsable(true), Personalizable(true), Bindable(true), Browsable(false), Category("Settings"), DefaultValue(""), WebPartStorage(Storage.Shared), FriendlyName("Enable Map Types"), Description("Map Types(Default,Satellite,Terrain).")]
        public bool enableMapTypes { get; set; }

        [WebBrowsable(true), Personalizable(true), Bindable(true), Browsable(false), Category("Settings"), DefaultValue(""), WebPartStorage(Storage.Shared), FriendlyName("ScrollControl"), Description("Map Scroll Control.")]
        public bool ScrollControl { get; set; }

        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            LiteralControl literalMap = new LiteralControl();
            LiteralControl googlemap = new LiteralControl();
            try
            {
                string height = (this.Height.ToString() == "") ? "300px" : this.Height.ToString();
                string width = (this.Width.ToString() == "") ? "100%" : this.Width.ToString(); ;
                literalMap.Text = "<div id='map_canvas' style='width:" + width + "; height:" + height + ";'></div>";

                //Attaching Google make URI and API key
                GetListAsString(this.ListName, ref jsArray, ref jsCenter);
                googlemap.Text = "<script src='http://maps.google.com/maps?file=api&amp;v=2&amp;key=" + this.APIKey + "' type='text/javascript'></script>" +
                                 "<script type='text/javascript'>" +
                                 "    function initializeGMap() " +
                                 "    {" +
                                 "        if (GBrowserIsCompatible()) {" +
                                 "        var map = new GMap2(document.getElementById('map_canvas'));" +
                                 "        map.setCenter(" + jsCenter + ", 13);" + // Set Center of Map
                                 "        " + jsArray + " " + // Add Points Array to Script
                                 ((this.enableScrollWheelZoom == true) ? "map.enableScrollWheelZoom();" : "") + //Mouse Scroll Wheel Zoom            
                                 ((this.ScrollControl == true) ? "map.addControl(new GLargeMapControl3D());" : ""); //Control Based Zoom

                // Attaching Map Types Browser   
                if (this.enableMapTypes == true)
                    googlemap.Text +=
                                 "        map.addMapType(G_PHYSICAL_MAP);" +
                                 "        var hControl = new GHierarchicalMapTypeControl();" +
                                 "        hControl.addRelationship(G_SATELLITE_MAP, G_HYBRID_MAP, 'Labels', false);" +
                                 "        map.addControl(hControl);";

                // Adding Long and Lat to Map Control
                googlemap.Text += "        for (var i = 0; i < mapPoints.bindings.length; i++) {" +
                                 "           var point = new GLatLng(mapPoints.bindings[i].Long,mapPoints.bindings[i].Lat);" +
                                 "           var marker = createMarker(point,mapPoints.bindings[i].Title); " +
                                 "           map.addOverlay(marker);" +
                                 "        }" +
                                 "       }" +
                                 "    }" +
                                 "$(document).ready(" +
                                 "     function(){" +
                                 "         initializeGMap();" +
                                 "});" +
                                 "function createMarker(point, info) { " +
                                 "        var marker = new GMarker(point);" +
                                 "        GEvent.addListener(marker, 'click', function() {marker.openInfoWindowHtml(info);}); " +
                                 "        return marker; " +
                                 "}  " +
                                 "</script>";

                Page.Header.Controls.Add(googlemap);
                this.Controls.Add(literalMap);
            }
            catch (Exception ex)
            {
                literalMap.Text = ex.Message;
            }
        }

        protected override void Render(HtmlTextWriter writer)
        {
            base.Render(writer);
        }

        protected void GetListAsString(string ListName, ref string jsArray, ref string jsCenter)
        {

            try
            {
                SPListCollection lists = SPContext.Current.Web.Lists;
                foreach (SPList list in lists)
                {
                    if (list.Title.ToLowerInvariant() == this.ListName.ToLowerInvariant())
                    {
                        jsArray += " var mapPoints = {'bindings': [";

                        foreach (SPListItem item in list.Items)
                        {
                            jsArray += "{'Title' : '" + item.Title.Trim() + "','Long': '" + item[this.LongField].ToString().Trim() + "', 'Lat': '" + item[this.LatField].ToString().Trim() + "'},";

                            if (item["IsCenter"].ToString().ToLowerInvariant() == "true")                            
                                jsCenter += "new GLatLng(" + item[this.LongField].ToString().Trim() + "," + item[this.LatField].ToString().Trim() + ")";
                        }
                        jsArray = jsArray.TrimEnd(',');
                        jsArray += "]};";
                    }
                }
            }
            catch (Exception ex)
            {

            }
        }
    }
}